<?php
/**
 * 文章模块
 */

class Post_Model extends CI_Model
{
    private $table  =   'post';
    private $id;

    public function __construct()
    {
        parent::__construct();
    }

    /**
     * 添加post
     * $data array
     */
    public function add($post, $type='article')
    {
        if(!is_array($post) || !count($post))
            return false;

        $data = array(
            'create_time' => date('Y-m-d H:i:s', time()),
            'active_time' => date('Y-m-d H:i:s', time()),
            'type' => $type
        );

        $data = array_merge($data, $post);
        $this->db->insert($this->table, $data);
        $this->id = $this->db->insert_id();

        if($type == 'article')
        {
            //更新tags信息
            $this->tags($post['tags']);
        }
        else
        {
            $this->db->set($type.'_num', $type.'_num + 1', false);
            $this->db->where('id', $post['pid']);
            $this->db->update($this->table);
        }
        return $this->id;
    }

    public function update($data, $id)
    {
        if(!is_array($data) || !count($data) || !$id)
            return false;
        $this->id = $id;
        $this->db->where('id', $this->id);
        $this->db->update($this->table, $data);
        if($this->db->affected_rows() > 0)
        {
            if($data['tags'])
            {
                $this->tags($data['tags']);
            }
            return true;
        }
        return false;
    }

    public function del($id)
    {
        $this->id = $id;
        //更新文章状态为1删除
        $this->db->update($this->table, array('state' => '1'), array('id' => $this->id));
        //更新tags
        if($this->db->affected_rows() > 0)
        {
            $this->tags();
            return true;
        }
        return false;
    }

    public function get($id)
    {
        if(!$id)
            return false;
        $this->db->where('id', $id);
        $query = $this->db->get($this->table);
        if($query->num_rows() > 0)
        {
            $article = $query->row();
            $article = (array) $article;
            //$article['title'] = title($article['title']);
            //$article['content'] = content($article['content']);
            //$article['tags'] = tags($article['tags']);

            $user = $this->user_model->find_by_id($article['author']);
            $article['user_email'] = $user->email;
            $article['user_name'] = $user->name;
            $article['user_id'] = $user->user_id;
            $article['user_avatar'] = get_gravatar($user->email, 20);
            
            return $article;
        }
        return false;
    }

    public function getArticles($offset=0, $limit=10)
    {
        $params = array(
            'field' => '*',
            'where' => array('type'=>'article', 'state'=>'0'),
            'order' => 'active_time DESC',
            'offset' => $offset,
            'limit' => $limit
        );
        return $this->getList($params);
    }

    public function getReviews($pid, $offset=0, $limit=20)
    {
        $params = array(
            'field' => 'id,pid,content,author,create_time,comment_num',
            'where' => array('pid'=>$pid, 'type'=>'review', 'state'=>'0'),
            'order' => 'create_time DESC',
            'offset' => $offset,
            'limit' => $limit
        );
        return $this->getList($params);
    }

    public function getComments($pid, $offset=0, $limit=20)
    {
        $params = array(
            'field' => 'id,pid,content,author,create_time',
            'where' => array('pid'=>$pid, 'type'=>'comment', 'state'=>'0'),
            'order' => 'create_time ASC',
            'offset' => $offset,
            'limit' => $limit
        );
        return $this->getList($params);
    }


    /**
     * 获得post列表
     * 
     * $params = array(
     *  'where' => array('type'=>'article', 'state'=>0),
     *  'order' => 'active_time DESC',
     *  'offset' => 0,
     *  'limit' => 10
     * );
     * @param <array> $params
     * @return <array>
     */
    public function getList($params = false)
    {
        if(!$params)
            return false;

        //计算总数
        if($params['where'])
            $this->db->where($params['where']);
        $this->db->from($this->table);
        $count = $this->db->count_all_results();
        
        if(!$count)
            return array('total'=>0, 'result'=>null);

        //按条件查询结果集
        $this->db->select($params['field']);
        $this->db->where($params['where']);
        if($params['order']) $this->db->order_by($params['order']);
        $this->db->limit($params['limit'], $params['offset']);
        $query = $this->db->get($this->table);
        $result = $query->result_array();
        if(count($result))
        foreach($result as $key => $val)
        {
            if(isset($val['title']))
                $result[$key]['title'] = title($val['title']);
            if(isset($val['content']))
                $result[$key]['content'] = content($val['content']);
            if(isset($val['tags']))
                $result[$key]['tags'] = tags($val['tags']);
            $user = $this->user_model->find_by_id($val['author']);
            $result[$key]['user_email'] = $user->email;
            $result[$key]['user_name'] = $user->name;
            $result[$key]['user_id'] = $user->user_id;
            $result[$key]['user_avatar'] = get_gravatar($user->email, 40);
        }
        
        return array(
            'total' => $count,
            'result' => $result
        );
    }

    public function getArticlesByTag($tag=false, $offset=0, $limit=10)
    {
        if(!$tag)
            return false;
        
        $params = array(
            'tag' => $tag,
            'offset' => $offset,
            'limit' => $limit
        );
        return $this->getListByTag($params);
    }

    /**
     * 按tag查找article
     * $params = array(
     *  'tag' => 'php',
     *  'offset' => '0',
     *  'limit' => '10'
     * );
     * @param <array> $params
     * @return <array>
     */
    public function getListByTag($params=false)
    {
        if(!$params)
            return false;
        /*
        $sql = " SELECT count(p.*) AS count FROM `tags` AS t
                 INNER JOIN `tag_post` AS tp ON t.tag_id = tp.tag_id
                 INNER JOIN `post` AS p ON tp.post = p.id
                 WHERE t.name = '{$this->db->escape($name)}' AND p.type = 'article' AND p.state = '0'";
        $query = $this->db->query($sql);
        $result = $query->row();
        $count = $result->count;
        */

        $this->db->select("{$this->table}.*");
        $this->db->from('tags');
        $this->db->join('tag_post', 'tags.tag_id = tag_post.tag_id');
        $this->db->join("{$this->table}", "tag_post.post_id = {$this->table}.id");
        $this->db->where('tags.name', $params['tag']);
        $this->db->where("{$this->table}.type", 'article');
        $this->db->where("{$this->table}.state", '0');
        $count = $this->db->count_all_results();
        
        if(!$count)
            return array('total'=>0, 'result'=>null);

        /*
        $sql = " SELECT * FROM `tags` AS t
                 INNER JOIN `tag_post` AS tp ON t.tag_id = tp.tag_id
                 INNER JOIN `post` AS p ON tp.post = p.id
                 WHERE t.name = '{$this->db->escape($name)}' AND p.type = 'article' AND p.state = '0'
                 ORDER BY p.create_time DESC 
                 LIMIT {$offset}, {$limit}";
        $query = $this->db->query($sql);
         * 
         */
        $this->db->select("{$this->table}.*");
        $this->db->from('tags');
        $this->db->join('tag_post', 'tags.tag_id = tag_post.tag_id');
        $this->db->join("{$this->table}", "tag_post.post_id = {$this->table}.id");
        $this->db->where('tags.name', $params['tag']);
        $this->db->where("{$this->table}.type", 'article');
        $this->db->where("{$this->table}.state", '0');
        $this->db->order_by("{$this->table}.create_time DESC");
        $this->db->limit($params['limit'], $params['offset']);
        $query = $this->db->get();
        $result = $query->result_array();
        if(count($result))
        foreach($result as $key => $val)
        {
            $result[$key]['title'] = title($val['title']);
            $result[$key]['content'] = content($val['content']);
            $result[$key]['tags'] = tags($val['tags']);
        }
        return array(
            'total' => $count,
            'result' => $result
        );
    }

    public function getTags($id=false)
    {
        if(!$id)
            return false;
        
        $return = array();
        $sql = " SELECT t.* FROM `tag_post` AS tp INNER JOIN `tags` AS t
                 ON tp.tag_id = t.tag_id WHERE tp.post_id = '{$id}'";
        $query = $this->db->query($sql);
        
        if($query->num_rows() > 0)
        {
            foreach($query->result() as $key => $row)
            {
                $return[$row->tag_id] = $row->name;
            }
        }
        return $return;
    }

    public function tags($tags)
    {
        $this->load->model('tag_model');

        //格式化当前tags字符串
        $arr_tags = $this->tag_model->formatTag($tags);

        //current tags
        $current_tags = $this->getTags($this->id);

        if(count($arr_tags) == 0 && count($current_tags) == 0)
            return false;

        if(count($arr_tags) == 0)
        {
            //这里把所有的tags数值递减
            $this->tag_model->updateNum('num-1', array_keys($current_tags));

            //清除tag_post中数据
            $this->db->where('post_id', $this->id);
            $this->db->where_in('tag_id', array_keys($current_tags));
            $this->db->delete('tag_post');
        }
        else
        {
            $new_tags = $old_tags = $exist_tags = $noexist_tags = array();
            
            $new_tags = array_diff($arr_tags, $current_tags);
            $old_tags = array_diff($current_tags, $arr_tags);

            if(count($new_tags) > 0)
            {
                $relationship_val = array();
                foreach($new_tags as $k => $v)
                {
                    if(empty($v))
                        continue;

                    $tag = $this->tag_model->get(array('name' => $v));
                    if($tag)
                    {
                        $exist_tags[$tag->tag_id] = $v;  //已存在的tags集合
                        $relationship_val[] = "($tag->tag_id, $this->id)";
                    }
                    else
                    {
                        $noexist_tags[] = $v;
                    }
                }

                //update
                if(count($exist_tags) > 0)
                {
                    $this->tag_model->updateNum('num+1', array_keys($exist_tags));

                    //insert
                    $sql = "INSERT INTO tag_post (tag_id, post_id) VALUES ".implode(',', $relationship_val);
                    $this->db->query($sql);
                }

                //insert tags
                if(count($noexist_tags) > 0)
                {
                    $relationship_val = array();
                    foreach($noexist_tags as $v)
                    {
                        $tag_id = $this->tag_model->add($v);
                        if(!$tag_id)
                            continue;
                        $relationship_val[] = "({$tag_id}, {$this->id})";
                    }
                    $sql = "INSERT INTO tag_post (tag_id, post_id) VALUES ".implode(',', $relationship_val);
                    $this->db->query($sql);
                }
            }
            
            //remove old_tags
            if(count($old_tags) > 0)
            {
                $old_tags_id = $this->tag_model->getIdByName($old_tags);

                //tags count - 1
                $this->tag_model->updateNum('num-1', $old_tags_id);

                $sql = "DELETE FROM tag_post WHERE post_id = '$this->id' AND tag_id IN (". implode(',', $old_tags_id) .")";
               $this->db->query($sql);
            }
        }

    }//end function
}